package com.qsw.permissionlib;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 动态权限工具，Activity或者Fragment中的onRequestPermissionsResult要交给该类的onRequestPermissionsResult处理
 */
public class PermissionManager {

    private Context mContext;

    private OnPermissionResult mOnPermissionResult;

    public PermissionManager(Context context, OnPermissionResult onPermissionResult) {
        mContext = context;
        mOnPermissionResult = onPermissionResult;
    }

    /**
     * 是否需要检查权限
     */
    private boolean needCheckPermission() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
    }

    /**
     * 判断是否需要申请权限的操作
     *
     * @param permission 要判断的权限
     * @return true需要，false不需要
     */
    public boolean shouldRequestPermission(String permission) {
        if (!needCheckPermission()) {
            return false;
        }
        return (ContextCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED);
    }

    /**
     * 检查参数中的所有权限是否都已授权，只要有一个未授权就返回false
     *
     * @param permissions 所有要检测的权限
     * @return true：全部已授权；false：至少一个未授权
     */
    public boolean checkPermissions(String[] permissions) {
        boolean result = true;
        if (needCheckPermission()) {
            for (String permission : permissions) {
                result = result && (ContextCompat.checkSelfPermission(mContext, permission) == PackageManager.PERMISSION_GRANTED);
            }
        }
        return result;
    }

    /**
     * 请求一次权限，判断是否曾被拒绝，若拒绝且选择了不再提醒，则不请求
     *
     * @param activity    环境
     * @param permission  要请求的权限
     * @param requestCode 请求码
     */
    public void requestPermission(Activity activity, String permission, int requestCode) {
        requestPermissionOnce(activity, permission, requestCode, false);
    }

    /**
     * 请求一次权限，无论是否已被拒绝，都请求一次
     *
     * @param activity    环境
     * @param permission  要请求的权限
     * @param requestCode 请求码
     */
    public void requestPermissionOnce(Activity activity, String permission, int requestCode) {
        requestPermissionOnce(activity, permission, requestCode, true);
    }

    /**
     * 请求一次权限
     *
     * @param activity    环境
     * @param permission  要请求的权限
     * @param once        true：无论是否已被拒绝，都请求一次；false：判断是否曾被拒绝，若拒绝且选择了不再提醒，则不请求
     * @param requestCode 请求码
     */
    private void requestPermissionOnce(Activity activity, String permission, int requestCode, boolean once) {
        if (!needCheckPermission()) {
            return;
        }
        // 判断是否已经赋予权限
        if (shouldRequestPermission(permission)) {
            // 如果应用之前请求过此权限但用户拒绝了请求，此方法将返回 true。
            if (!once
                    && !ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
                    && (SPUtil.getPermissionDeniedCount(activity, permission) > 0)) {
                // 拒绝并不再提示
                if (mOnPermissionResult != null) {
                    mOnPermissionResult.onDeniedEver(new String[]{permission}, requestCode);
                }
            } else {
                // 申请权限，字符串数组内是一个或多个要申请的权限，requestCode是申请权限结果的返回参数，在onRequestPermissionsResult可以得知申请结果
                ActivityCompat.requestPermissions(activity, new String[]{permission}, requestCode);
            }
        } else {
            if (mOnPermissionResult != null) {
                mOnPermissionResult.onPass(new String[]{permission}, requestCode);
            }
        }
    }

    /**
     * 请求权限，判断是否曾被拒绝，若拒绝且选择了不再提醒，则不请求
     *
     * @param activity    环境
     * @param permissions 要请求的权限数组
     * @param requestCode 请求码
     */
    public void requestPermission(Activity activity, String[] permissions, int requestCode) {
        if (!needCheckPermission()) {
            return;
        }
        List<String> passPermissionsList = new ArrayList<>();
        List<String> deniedEverPermissionsList = new ArrayList<>();
        for (String permission : permissions) {
            // 判断是否已经赋予权限
            if (shouldRequestPermission(permission)) {
                // 如果应用之前请求过此权限但用户拒绝了请求，此方法将返回 true。
                if (!ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
                        && (SPUtil.getPermissionDeniedCount(activity, permission) > 0)) {
                    // 拒绝并不再提示
                    deniedEverPermissionsList.add(permission);
                } else {
                    // 申请权限，字符串数组内是一个或多个要申请的权限，requestCode是申请权限结果的返回参数，在onRequestPermissionsResult可以得知申请结果
                    ActivityCompat.requestPermissions(activity, permissions, requestCode);
                }
            } else {
                passPermissionsList.add(permission);
            }
        }
        if (mOnPermissionResult != null) {
            if (passPermissionsList.size() > 0) {
                String[] passPermissionsArray = new String[passPermissionsList.size()];
                passPermissionsList.toArray(passPermissionsArray);
                mOnPermissionResult.onPass(passPermissionsArray, requestCode);
            }
            if (deniedEverPermissionsList.size() > 0) {
                String[] deniedEverPermissionsArray = new String[deniedEverPermissionsList.size()];
                deniedEverPermissionsList.toArray(deniedEverPermissionsArray);
                mOnPermissionResult.onDeniedEver(deniedEverPermissionsArray, requestCode);
            }
        }
    }

    /**
     * 处理权限授予结果
     *
     * @param requestCode  请求码
     * @param permissions  来自Activity中的回调方法参数
     * @param grantResults 来自Activity中的回调方法参数
     */
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        List<String> passPermissionsList = new ArrayList<>();
        List<String> deniedPermissionsList = new ArrayList<>();
        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                SPUtil.addPermissionDeniedCount(mContext, permissions[i]);
                deniedPermissionsList.add(permissions[i]);
            } else {
                passPermissionsList.add(permissions[i]);
            }
        }
        if (mOnPermissionResult != null) {
            if (passPermissionsList.size() > 0) {
                String[] passPermissionsArray = new String[passPermissionsList.size()];
                passPermissionsList.toArray(passPermissionsArray);
                mOnPermissionResult.onPass(passPermissionsArray, requestCode);
            }
            if (deniedPermissionsList.size() > 0) {
                String[] deniedPermissionsArray = new String[deniedPermissionsList.size()];
                deniedPermissionsList.toArray(deniedPermissionsArray);
                mOnPermissionResult.onDenied(deniedPermissionsArray, requestCode);
            }
        }
    }

    /**
     * 弹出权限被拒后的说明及申请框
     *
     * @param activity         环境
     * @param title            弹框标题
     * @param negativeStr      弹框取消按钮文字
     * @param positiveStr      弹框跳转到权限设置界面的文字，若为null或空字符串，则不显示
     * @param msg              文字说明，若为null或空字符串，则不显示
     * @param onCancelListener 当取消按钮被点击时的回调，可为null
     */
    public void showDeniedDialog(Activity activity, String title, String negativeStr, String positiveStr, String msg,
                                 final DialogInterface.OnCancelListener onCancelListener) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(activity);
        builder.setTitle(title);
        builder.setNegativeButton(negativeStr, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                if (onCancelListener != null) {
                    onCancelListener.onCancel(dialog);
                }
            }
        });
        if (!TextUtils.isEmpty(positiveStr)) {
            builder.setPositiveButton(positiveStr, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    Uri packageURI = Uri.parse("package:" + mContext.getPackageName());
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                    mContext.startActivity(intent);
                }
            });
        }
        if (!TextUtils.isEmpty(msg)) {
            builder.setMessage(msg);
        }
        if (onCancelListener != null) {
            builder.setOnCancelListener(onCancelListener);
        }
        builder.show();
    }

}